{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task4 建模调参 \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 线性模型\n",
    "- 交叉验证\n",
    "- 模拟真实业务"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# reduce_mem_usage 函数通过调整数据类型，帮助我们减少数据在内存中占用的空间\n",
    "def reduce_mem_usage(df):\n",
    "    \"\"\" iterate through all the columns of a dataframe and modify the data type\n",
    "        to reduce memory usage.        \n",
    "    \"\"\"\n",
    "    start_mem = df.memory_usage().sum() \n",
    "    print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))\n",
    "    \n",
    "    for col in df.columns:\n",
    "        col_type = df[col].dtype\n",
    "        \n",
    "        if col_type != object:\n",
    "            c_min = df[col].min()\n",
    "            c_max = df[col].max()\n",
    "            if str(col_type)[:3] == 'int':\n",
    "                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:\n",
    "                    df[col] = df[col].astype(np.int8)\n",
    "                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n",
    "                    df[col] = df[col].astype(np.int16)\n",
    "                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n",
    "                    df[col] = df[col].astype(np.int32)\n",
    "                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n",
    "                    df[col] = df[col].astype(np.int64)  \n",
    "            else:\n",
    "                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n",
    "                    df[col] = df[col].astype(np.float16)\n",
    "                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n",
    "                    df[col] = df[col].astype(np.float32)\n",
    "                else:\n",
    "                    df[col] = df[col].astype(np.float64)\n",
    "        else:\n",
    "            df[col] = df[col].astype('category')\n",
    "\n",
    "    end_mem = df.memory_usage().sum() \n",
    "    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))\n",
    "    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))\n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Memory usage of dataframe is 43164344.00 MB\n",
      "Memory usage after optimization is: 11482985.00 MB\n",
      "Decreased by 73.4%\n"
     ]
    }
   ],
   "source": [
    "sample_feature = reduce_mem_usage(pd.read_csv('data_for_tree.csv'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "continuous_feature_names = [x for x in sample_feature.columns if x not in ['price','brand','model','brand']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  线性模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_feature = sample_feature.dropna().replace('-', 0).reset_index(drop=True)\n",
    "sample_feature['notRepairedDamage'] = sample_feature['notRepairedDamage'].astype(np.float32)\n",
    "train = sample_feature[continuous_feature_names + ['price']]\n",
    "\n",
    "train_X = train[continuous_feature_names]\n",
    "train_y = train['price']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 4.4.2 - 1 简单建模"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = LinearRegression(normalize=True)\n",
    "model = model.fit(train_X, train_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "subsample_index = np.random.randint(low=0, high=len(train_y), size=50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The predicted price is obvious different from true price\n"
     ]
    },
    {
     "data": {
      "image/png": "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HSmoiEhZlbuDxnXXXcfUqVM5/vjj+1Q5XX/99Tz88MNMmjSJCRMmcOONN0byfRdffDEf/vCHmTRpEgcddBC33XYbO+ywA7fffjuXXXYZBx10EAcffDCPPfZYJN9XapZa9BsKmpubXQ/pEimu5557jv33TzeARnqdnZ20trayatUqGhoaaGtrU9taGaX7+5nZEndvHmxdtamISNmpg0b1UPWXiIhERkFFREQio6AiIiKRUVAREZHIKKiIiEhkFFREpCrV1tbS1NTExIkTOfPMM7cbCiYXDz30EKeeeioA8+fP59prr8247DvvvLNtkMhcXH311fzHf/xH2vTeofsnTpzI/Pnpn/AxWL5KRUFFRKrSjjvuyNKlS3nmmWcYMWIEN9xwQ5/57s7WrVtz3u6nPvUpLr/88ozz8w0qA7n00ktZunQpv/zlL7nwwgu3y/fmzZsHzVepKKiISNl1dkJjI9TUBK9RD1B89NFH09XVxcqVK9l///350pe+tG3o+3vvvZcjjjiCQw45hDPPPJP169cD8Lvf/Y799tuPo446ijvuuGPbtm6++WYuueQSIBge//TTT+eggw7ioIMO4o9//COXX345L774Ik1NTXzjG98A4Lvf/S6HHXYYkyZN4qqrrtq2rba2Nvbdd19OOOGEPoNXZrL//vszbNgw3nzzTc4//3wuu+wyjj32WL75zW8Omi+Ajo4ODj/8cJqamrj44ou3DRUTJQUVESmrzk5oaYHubnAPXltaogssmzdv5u677+bAAw8E4Pnnn+fcc8/lySefZKedduKaa65hwYIFPPHEEzQ3N/P973+f9957jy984Qv89re/ZeHChfzv//5v2m1/9atf5ZhjjuGpp57iiSee4IADDuDaa69ln332YenSpXz3u9/l3nvvZfny5SxatIilS5eyZMkS/vCHP7BkyRLmzp3Lk08+yR133MHjjz8+6L489thj1NTUMGbMGABeeOEFFixYwPe+971B8/Xcc88xb948Hn74YZYuXUptbW1RHi+gO+pFpKxaW6F/c0dPT5BeyE32GzZs2PZgrKOPPpqLLrqIV199lUQiweTJkwF49NFHefbZZznyyCOBYCDHI444gj//+c+MGzeO8ePHA3DOOefQ3t6+3Xc88MAD3HLLLUDQhrPLLrvw9ttv91nm3nvv5d577+Xggw8GYP369Sxfvpx1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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(train_X['v_9'][subsample_index], train_y[subsample_index], color='black')\n",
    "plt.scatter(train_X['v_9'][subsample_index], model.predict(train_X.loc[subsample_index]), color='blue')\n",
    "plt.xlabel('v_9')\n",
    "plt.ylabel('price')\n",
    "plt.legend(['True Price','Predicted Price'],loc='upper right')\n",
    "print('The predicted price is obvious different from true price')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "绘制特征v_9的值与标签的散点图，图片发现模型的预测结果（蓝色点）与真实标签（黑色点）的分布差异较大，且部分预测值出现了小于0的情况，说明我们的模型存在一些问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "It is clear to see the price shows a typical exponential distribution\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x158d570cba8>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "print('It is clear to see the price shows a typical exponential distribution')\n",
    "plt.figure(figsize=(15,5))\n",
    "plt.subplot(1,2,1)\n",
    "sns.distplot(train_y)\n",
    "plt.subplot(1,2,2)\n",
    "sns.distplot(train_y[train_y < np.quantile(train_y, 0.9)])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数据的标签（price）呈现长尾分布，不利于我们的建模预测。原因是很多模型都假设数据误差项符合正态分布，而长尾分布的数据违背了这一假设。参考博客：https://blog.csdn.net/Noob_daniel/article/details/76087829"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在这里我们对标签进行了 $log(x+1)$ 变换，使标签贴近于正态分布"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_y_ln = np.log(train_y + 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = model.fit(train_X, train_y_ln)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "再次进行可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The predicted price seems normal after np.log transforming\n"
     ]
    },
    {
     "data": {
      "image/png": "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0NDAz39+LInEpzEbQSLxaX7+82PzUgUi8dHc3ExV1bbtZlVVVWm750bt6quvZubMmUyfPn2bKqfrr7+eRx99lMmTJzNx4kRuuummSL7vvPPO4+Mf/ziTJ09mypQp3Hnnneywww7cddddXHzxxUyZMoWDDz6YJ554IpLvKzRLLvoNB/X19a5JukTy64UXXuCAA1LdQZBaa2srTU1NdHV1UVNTQ3Nzsy4miijV38/Mlrl7/WDrakBJESm6hoYGBZEyoeovERGJjIKKiIhERkFFREQio6AiIiKRUVAREZHIKKiISFmqrKykrq6OSZMmcdppp203FEw2HnnkEU466SQAFi5cyFVXXZV22bfffnvrIJHZuOKKK/iXf/mXlOl9Q/dPmjSJhQtTD3E4WL4KRUFFRMrSjjvuSFtbG8899xyjRo3ipz/96Tafuzu9vb1Zb/fzn/88l1ySfvbyXIPKQC666CLa2tr45S9/yTnnnLNdvjdv3jxovgpFQUVEii7fk7MdffTRtLe309HRwQEHHMD555+/dej7Bx54gCOOOIKpU6dy2mmn8e67wVQL//M//8P+++/PUUcdxd133711W7fccgsXXHABEAyPf8oppzBlyhSmTJnCH//4Ry655BJWr15NXV0d3/nOdwD40Y9+xKGHHsrkyZO5/PLLt26rubmZ/fbbj2OPPXabwSvTOeCAAxgxYgRvvfUWX/nKV7j44ov5zGc+w3e/+91B8wUwf/58DjvsMOrq6jjvvPO2DhUTJQUVESmq1lZobAwmZXMPnhsbowssmzdv5r777uOggw4CYOXKlZx11lksX76cnXbaiSuvvJKHHnqIp556ivr6eq655href/99vva1r/Gb3/yGxYsX83//938pt/2Nb3yDY445hqeffpqnnnqKAw88kKuuuop9992XtrY2fvSjH/HAAw+watUqlixZQltbG8uWLeMPf/gDy5YtY8GCBSxfvpy7776bJ598ctDf8sQTT1BRUUHfvFAvvvgiDz30ED/+8Y8HzdcLL7zAHXfcwaOPPkpbWxuVlZV5mV5Ad9SLSFE1NUH/5o6eniB9KDfZb9y4cevEWEcffTTnnnsur732GolEgmnTpgHw+OOP8/zzz3PkkUcCwUCORxxxBH/6058YP348EyZMAODMM8+kpaVlu+/43e9+x2233QYEbTi77ror69ev32aZ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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(train_X['v_9'][subsample_index], train_y[subsample_index], color='black')\n",
    "plt.scatter(train_X['v_9'][subsample_index], np.exp(model.predict(train_X.loc[subsample_index])), color='blue')\n",
    "plt.xlabel('v_9')\n",
    "plt.ylabel('price')\n",
    "plt.legend(['True Price','Predicted Price'],loc='upper right')\n",
    "print('The predicted price seems normal after np.log transforming')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "发现预测结果与真实值较为接近，且未出现异常状况"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "####  五折交叉验证"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.metrics import mean_absolute_error,  make_scorer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def log_transfer(func):\n",
    "    def wrapper(y, yhat):\n",
    "        result = func(np.log(y), np.nan_to_num(np.log(yhat)))\n",
    "        return result\n",
    "    return wrapper"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.\n",
      "[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:    0.2s finished\n"
     ]
    }
   ],
   "source": [
    "scores = cross_val_score(model, X=train_X, y=train_y, verbose=1, cv = 5, scoring=make_scorer(log_transfer(mean_absolute_error)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用线性回归模型，对未处理标签的特征数据进行五折交叉验证（Error 1.36）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AVG: 1.1669861056619866\n"
     ]
    }
   ],
   "source": [
    "print('AVG:', np.mean(scores))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用线性回归模型，对处理过标签的特征数据进行五折交叉验证（Error 0.19）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.\n",
      "[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:    0.2s finished\n"
     ]
    }
   ],
   "source": [
    "scores = cross_val_score(model, X=train_X, y=train_y_ln, verbose=1, cv = 5, scoring=make_scorer(mean_absolute_error))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AVG: 0.2044885035011954\n"
     ]
    }
   ],
   "source": [
    "print('AVG:', np.mean(scores))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cv1</th>\n",
       "      <th>cv2</th>\n",
       "      <th>cv3</th>\n",
       "      <th>cv4</th>\n",
       "      <th>cv5</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>MAE</th>\n",
       "      <td>0.199593</td>\n",
       "      <td>0.205275</td>\n",
       "      <td>0.20748</td>\n",
       "      <td>0.202984</td>\n",
       "      <td>0.207111</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          cv1       cv2      cv3       cv4       cv5\n",
       "MAE  0.199593  0.205275  0.20748  0.202984  0.207111"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scores = pd.DataFrame(scores.reshape(1,-1))\n",
    "scores.columns = ['cv' + str(x) for x in range(1, 6)]\n",
    "scores.index = ['MAE']\n",
    "scores"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "####  模拟真实业务情况"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "事实上，由于我们并不具有预知未来的能力，五折交叉验证在某些与时间相关的数据集上反而反映了不真实的情况。通过2018年的二手车价格预测2017年的二手车价格，这显然是不合理的，因此我们还可以采用时间顺序对数据集进行分隔。在本例中，我们选用靠前时间的4/5样本当作训练集，靠后时间的1/5当作验证集，最终结果与五折交叉验证差距不大"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "import datetime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_feature = sample_feature.reset_index(drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "split_point = len(sample_feature) // 5 * 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "train = sample_feature.loc[:split_point].dropna()\n",
    "val = sample_feature.loc[split_point:].dropna()\n",
    "\n",
    "train_X = train[continuous_feature_names]\n",
    "train_y_ln = np.log(train['price'] + 1)\n",
    "val_X = val[continuous_feature_names]\n",
    "val_y_ln = np.log(val['price'] + 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = model.fit(train_X, train_y_ln)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.20709570405998082"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_absolute_error(val_y_ln, model.predict(val_X))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 非线性模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.tree import DecisionTreeRegressor\n",
    "from sklearn.ensemble import RandomForestRegressor\n",
    "from sklearn.ensemble import GradientBoostingRegressor\n",
    "from sklearn.neural_network import MLPRegressor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "models = [LinearRegression(),\n",
    "          DecisionTreeRegressor(),\n",
    "          RandomForestRegressor(),\n",
    "          GradientBoostingRegressor(),\n",
    "          MLPRegressor(solver='lbfgs', max_iter=100), \n",
    "          ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LinearRegression is finished\n",
      "DecisionTreeRegressor is finished\n",
      "RandomForestRegressor is finished\n",
      "GradientBoostingRegressor is finished\n",
      "MLPRegressor is finished\n"
     ]
    }
   ],
   "source": [
    "result = dict()\n",
    "for model in models:\n",
    "    model_name = str(model).split('(')[0]\n",
    "    scores = cross_val_score(model, X=train_X, y=train_y_ln, verbose=0, cv = 5, scoring=make_scorer(mean_absolute_error))\n",
    "    result[model_name] = scores\n",
    "    print(model_name + ' is finished')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>LinearRegression</th>\n",
       "      <th>DecisionTreeRegressor</th>\n",
       "      <th>RandomForestRegressor</th>\n",
       "      <th>GradientBoostingRegressor</th>\n",
       "      <th>MLPRegressor</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>cv1</th>\n",
       "      <td>0.199085</td>\n",
       "      <td>0.215555</td>\n",
       "      <td>0.156401</td>\n",
       "      <td>0.173955</td>\n",
       "      <td>274.797655</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cv2</th>\n",
       "      <td>0.205135</td>\n",
       "      <td>0.213920</td>\n",
       "      <td>0.158127</td>\n",
       "      <td>0.179256</td>\n",
       "      <td>319.417689</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cv3</th>\n",
       "      <td>0.204186</td>\n",
       "      <td>0.208592</td>\n",
       "      <td>0.155354</td>\n",
       "      <td>0.177347</td>\n",
       "      <td>293.979359</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cv4</th>\n",
       "      <td>0.205378</td>\n",
       "      <td>0.209651</td>\n",
       "      <td>0.156504</td>\n",
       "      <td>0.177923</td>\n",
       "      <td>177.163494</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cv5</th>\n",
       "      <td>0.203863</td>\n",
       "      <td>0.218583</td>\n",
       "      <td>0.160168</td>\n",
       "      <td>0.176365</td>\n",
       "      <td>439.143928</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     LinearRegression  DecisionTreeRegressor  RandomForestRegressor  \\\n",
       "cv1          0.199085               0.215555               0.156401   \n",
       "cv2          0.205135               0.213920               0.158127   \n",
       "cv3          0.204186               0.208592               0.155354   \n",
       "cv4          0.205378               0.209651               0.156504   \n",
       "cv5          0.203863               0.218583               0.160168   \n",
       "\n",
       "     GradientBoostingRegressor  MLPRegressor  \n",
       "cv1                   0.173955    274.797655  \n",
       "cv2                   0.179256    319.417689  \n",
       "cv3                   0.177347    293.979359  \n",
       "cv4                   0.177923    177.163494  \n",
       "cv5                   0.176365    439.143928  "
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result = pd.DataFrame(result)\n",
    "result.index = ['cv' + str(x) for x in range(1, 6)]\n",
    "result"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "随机森林模型取得了更好的效果"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
